home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 424_01 / ed_157 / help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-10  |  6.8 KB  |  295 lines

  1. /*
  2.  * Copyright (C) 1992 by Rush Record (rhr@clio.rice.edu)
  3.  * 
  4.  * This file is part of ED.
  5.  * 
  6.  * ED is free software; you can redistribute it and/or modify it under the terms
  7.  * of the GNU General Public License as published by the Free Software Foundation.
  8.  * 
  9.  * ED is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  10.  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  11.  * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  12.  * 
  13.  * You should have received a copy of the GNU General Public License along with ED
  14.  * (see the file COPYING).  If not, write to the Free Software Foundation, 675
  15.  * Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17. #include "opsys.h"
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21.  
  22. #include "memory.h"
  23. #include "ctyp_dec.h"
  24. #include "rec.h"
  25. #include "window.h"
  26. #include "ed_dec.h"
  27. #include "library.h"
  28.  
  29. static topic_ptr base = NULL;
  30.  
  31. extern Char *exefile();
  32. extern Char *filename();
  33.  
  34. /******************************************************************************\
  35. |Routine: help_disp
  36. |Callby: help
  37. |Purpose: Displays help text.
  38. |Arguments:
  39. |    cur is the topic containing the text to be displayed.
  40. \******************************************************************************/
  41. void help_disp(cur)
  42. topic_ptr cur;
  43. {
  44.     Int i;
  45.     Char *p,*q;
  46.     Schar key;
  47.     
  48.     next();
  49.     putz(cur->topic);
  50.     next();
  51.     i = 3;
  52.     p = (char *)cur->text;
  53.     while((q = strchr(p,'\n')))
  54.     {
  55.         *q = '\0';
  56.         putz(p);
  57.         next();
  58.         *q = '\n';
  59.         if(!*(p = ++q))
  60.             return;
  61.         if(++i >= NROW)
  62.         {
  63.             reverse();
  64.             putz(" ==<space> to continue,b to back up,q to quit==> ");
  65.             normal();
  66.             get_next_key(&key);
  67.             cr();
  68.             ers_end();
  69.             if(tolower(key) == 'q' || key == 3 || key == 25)    /* emulate more quit command */
  70.                 return;
  71.             if(tolower(key) == 'b')    /* emulate more backup command */
  72.             {
  73.                 q = p;
  74.                 for(i = NROW * 5 / 3;i--;)
  75.                 {
  76.                     if(q == (Char *)cur->text)
  77.                         break;
  78.                     q--;
  79.                     while(*--q != '\n')
  80.                         if(q == (Char *)cur->text)
  81.                             break;
  82.                     if(q == (Char *)cur->text)
  83.                         break;
  84.                     q++;
  85.                 }
  86.                 p = q;
  87.             }
  88.             i = 1;
  89.         }
  90.     }
  91. }
  92.  
  93. /******************************************************************************\
  94. |Routine: help_keywords
  95. |Callby: help
  96. |Purpose: Displays the keywords of additional topics that are available.
  97. |Arguments:
  98. |    cur is the topic for which additional subtopics might be displayed.
  99. \******************************************************************************/
  100. void help_keywords(cur)
  101. topic_ptr cur;
  102. {
  103.     Char buf[512],*p;
  104.     Int col,i,l,size;
  105.     subtopic_ptr scan;
  106.  
  107.     col = 0;
  108.     for(scan = cur->first;scan != 0;scan = scan->next)
  109.     {
  110.         if(!col)
  111.         {
  112.             putz("Additional information available:");
  113.             next();
  114.             next();
  115.         }
  116.         l = strlen(scan->keyword);
  117.         if(l <= 10)
  118.             size = 12;
  119.         else
  120.             size = 24;
  121.         if(col + size >= NCOL)
  122.         {
  123.             putz(buf);
  124.             next();
  125.             col = 0;
  126.         }
  127.         sprintf(buf + col,"  %s",scan->keyword);
  128.         for(i = 0,p = buf + col + l + 2;i < size - (l + 2);i++)
  129.             *p++ = ' ';
  130.         *p++ = '\0';
  131.         col += size;
  132.     }
  133.     if(col != 0)
  134.     {
  135.         putz(buf);
  136.         next();
  137.     }
  138.     next();
  139. }
  140.  
  141. /******************************************************************************\
  142. |Routine: help
  143. |Callby: command
  144. |Purpose: Implements VMS-style online help.
  145. |Arguments:
  146. |    token is a string that may contain keywords to be searched for.
  147. \******************************************************************************/
  148. void help(token)
  149. Char *token;
  150. {
  151.     FILE *fp;
  152.     Int j,k,l,ncom,hits,save_botrow;
  153.     topic_ptr cur,temp;
  154.     subtopic_ptr scan;
  155.     Char *c;
  156.     Char helpfile[512],prompt[256],buf[512],tok[128],commands[64][5],hit[128];    /* no more than 128 subtopics are allowed */
  157.  
  158. /* load the help file if it isn't already loaded */
  159.     if(!base)
  160.     {
  161.         strcpy(helpfile,exefile());
  162.         strcpy(filename(helpfile),"ed.hlp");
  163.         if(!(fp = fopen(helpfile,"r")))
  164.         {
  165.             sprintf(buf,"Unable to open the help file '%s'.",helpfile);
  166.             slip_message(buf);
  167.             wait_message();
  168.             return;
  169.         }
  170.         help_load(fp,&base);
  171.         fclose(fp);
  172.     }
  173.     if(!base)
  174.         return;
  175. /* remove trailing whitespace */
  176.     for(c = token + strlen(token);isspace(*--c);)
  177.         if(c == token)
  178.         {
  179.             c--;
  180.             break;
  181.         }
  182.     *++c = '\0';
  183. /* prepare for search */
  184.     marge(1,NROW);
  185.     move(NROW,1);
  186.     save_botrow = BOTROW;
  187.     BOTROW = NROW;
  188.     next();
  189.     putout();
  190.     cur = base;
  191.     if(!*token)
  192.     {
  193.         help_disp(cur);    /* display help text for this node in tree */
  194.         help_keywords(cur);    /* display keywords for additional info */
  195.     }
  196.     while(1)
  197.     {
  198.         if(!cur->first)    /* no additional exploration possible from here, pop up in tree */
  199.         {
  200.             cur = cur->parent;
  201.             continue;
  202.         }
  203.         if(!*token)    /* if no more input is in the buffer, ask for more */
  204.         {
  205.             c = prompt + (sizeof(prompt) - sizeof("subtopic? ") - 1); /* build the prompt string backwards */
  206.             strcpy(c,"subtopic? ");
  207.             for(temp = cur;temp;temp = temp->parent)
  208.             {
  209.                 *--c = ' ';
  210.                 l = strlen(temp->topic);
  211.                 c -= l;
  212.                 memcpy(c,temp->topic,l);
  213.             }
  214.             l = inquire(c,buf,sizeof(buf),1);    /* get user keyword prompt response */
  215.             token = buf;
  216.         }
  217. /* parse the next token from whichever input */
  218.         while(isspace(*token))
  219.             token++;
  220.         c = tok;
  221.         while(!isspace(*token) && *token)
  222.             *c++ = *token++;
  223.         *c = '\0';
  224.         l = c - tok;
  225.         while(isspace(*token))    /* this is so we can decide whether to display help yet below */
  226.             token++;
  227. /* no input means pop up or out */
  228.         if(!l)
  229.         {
  230.             if(!(cur = cur->parent))    /* he hits return, go up in tree or exit if at root */
  231.             {
  232.                 marge(TOPROW,BOTROW = save_botrow);
  233.                 ref_display();
  234.                 return;
  235.             }
  236.             continue;
  237.         }
  238. /* redisplay keywords if they enter ? */
  239.         c = tok;    /* this is expected in the keyword comparisons below */
  240.         if(*c == '?')
  241.         {
  242.             help_keywords(cur);    /* display keywords for additional info */
  243.             continue;
  244.         }
  245. /* load all the keywords at this level into the array */
  246.         for(ncom = 0,scan = cur->first;scan != 0;scan = scan->next)
  247.         {
  248.             memcpy(commands[ncom],scan->keyword,4);
  249.             commands[ncom++][4] = '\0';
  250.         }
  251.         memset(hit,1,ncom);
  252.         for(j = 0;j < 4;j++)    /* examine four columns in command array */
  253.         {
  254.             for(k = 0;k < ncom;k++)    /* knock out mismatches */
  255.                 if(tolower(commands[k][j]) != tolower(*c))
  256.                     hit[k] = 0;
  257.             for(hits = k = 0;k < ncom;k++)    /* count remaining matches */
  258.                 hits += hit[k];
  259.             if(!hits)
  260.             {
  261.                 sprintf(buf,"'%s' doesn't match any of the choices.",tok);
  262.                 putz(buf);
  263.                 next();
  264.                 next();
  265.                 help_keywords(cur);
  266.                 *token = '\0';
  267.                 break;
  268.             }
  269.             else if(hits == 1)
  270.             {
  271.                 for(scan = cur->first,c = hit;!*c++;scan = scan->next);    /* find the entry for their keyword */
  272.                 cur = scan->child;
  273.                 if(!*token)
  274.                 {
  275.                     help_disp(cur);    /* display help text for this node in tree */
  276.                     help_keywords(cur);    /* display keywords for additional info */
  277.                 }
  278.                 break;
  279.             }
  280.             c++;
  281.             if(!*c || isspace(*c))
  282.             {
  283.                 sprintf(buf,"'%s' is ambiguous, please supply more characters.",tok);
  284.                 putz(buf);
  285.                 next();
  286.                 next();
  287.                 help_keywords(cur);
  288.                 *token = '\0';
  289.                 break;
  290.             }
  291.         }
  292.     }
  293. }
  294.  
  295.